<template>
    <div class="console-page batch-etl forbid-select">
        <el-steps style="padding: 10px;" :active="activeStep" align-center process-status="finish"
            finish-status="success">
            <el-step v-for="(item, index) in step" :title="item" :key="index" />
        </el-steps>
        <div class="step-content">
            <batch-reader :db="db" :dbTypes="dbTypes" @change="readerConfigChange" :active="readerActive"
                v-show="readerActive" ref="readerRef" class="etl-step" id="step-0" />
            <batch-writer :db="db" :dbTypes="dbTypes" :readerTable="summaryConfig.reader?.selectTable"
                @change="writerConfigChange" :active="writerActive" :readerDb="summaryConfig.reader?.dbSequence"
                v-show="writerActive" ref="writerRef" class="etl-step" id="step-1" />
            <batch-mapping :config="summaryConfig" @change="mappingChange" :active="mappingActive" :db="db"
                :etlConfig="etlConfig" v-show="mappingActive" ref="mappingRef" class="etl-step" id="step-2" />
            <batch-confirm v-show="confirmActive" :config="summaryConfig" :active="confirmActive" class="etl-step"
                id="step-3" :etlConfig="etlConfig" />
        </div>
        <div class="step-controller">
            <el-button type="primary" class="fit-auto-resize" @click="prev" :disabled="activeStep <= 0"
                :style="`opacity: ${activeStep === 0 ? 0 : 1};`">上一步</el-button>
            <el-button type="primary" class="fit-auto-resize" @click="next" :disabled="!allowNext"
                v-if="activeStep !== step.length - 1">下一步</el-button>
            <el-button type="primary" class="fit-auto-resize" @click="submit" v-else
                confirm-title="确认提交任务?">提交任务</el-button>
        </div>
    </div>
</template>

<script setup>
import { useRequest, useElMessage } from "@usehook"
import storeInstance from "@/pinia"
import router from '@/router'
import { broadcastEmitter } from "@/utils/eventbus"

let activeStep = $ref(0)
let summaryConfig = $ref({ reader: { selectTable: [] }, writer: {} })
let etlConfig = $ref({})
let dbTypes = $ref([])
let db = $ref({})
const { tagMenuStore } = storeInstance

const step = ["表输入(Reader)", "表输出(Writer)及映射", "字段映射", "导入任务"]

const readerActive = $computed(() => activeStep === 0)
const writerActive = $computed(() => activeStep === 1)
const mappingActive = $computed(() => activeStep === 2)
const confirmActive = $computed(() => activeStep === 3)

const readerConfigChange = (config) => {
    etlConfig = {}
    for (let table of config.selectTable) {
        etlConfig[table] = {
            in: {
                table,
                onlyChecked: false,
                dbType: config.dbType,
                dbSequence: config.dbSequence,
                customize: false,
                customizeSql: "",
                column: "",
                tableColumn: ""
            },
            taskName: table
        }
    }
    summaryConfig.reader = config
}

const writerConfigChange = (config) => {
    for (let table of Object.keys(config.tableMapping)) {
        const writeTable = config.tableMapping[table]
        if (!writeTable) continue
        etlConfig[table].out = {
            table: writeTable,
            onlyChecked: false,
            dbType: config.dbType,
            dbSequence: config.dbSequence,
            column: "",
            tableColumn: ""
        }
        etlConfig[table].front = {
            sql: "",
            dbSequence: config.dbSequence
        }
        etlConfig[table].rear = {
            sql: "",
            dbSequence: config.dbSequence
        }
    }
    summaryConfig.writer = config
}

const allowNext = $computed(() => {
    if (activeStep >= step.length - 1) return false
    if (readerActive && !summaryConfig.reader.selectTable.length) {
        return false
    }
    if (writerActive) {
        let writer = 0
        for (let readerTable of summaryConfig.reader.selectTable) {
            if (summaryConfig.writer.tableMapping[readerTable]) writer += 1
        }
        if (writer != summaryConfig.reader.selectTable.length) return false
    }
    if (mappingActive) {
        for (let ex of Object.values(etlConfig)) {
            if (ex.in.column.split(";")?.length !== ex.out.column.split(";")?.length) return false
        }
    }
    return true
})

const getConnection = () => {
    useRequest({ url: "/data/connection/getConnection" }).then(resp => {
        if (resp && resp.status) {
            dbTypes = resp.data.dbTypes
            db = resp.data.db
        }
    })
}

const mappingChange = (config) => {
    for (let table of Object.keys(config)) {
        if (!etlConfig[table]) continue
        if (config[table].readerColumn) etlConfig[table].in.column = config[table].readerColumn.join(";")
        if (etlConfig[table].in) etlConfig[table].in.tableColumn = JSON.stringify(config[table].allReaderColumn)
        if (config[table].writerColumn) etlConfig[table].out.column = config[table].writerColumn.join(";")
        if (etlConfig[table].out) etlConfig[table].out.tableColumn = JSON.stringify(config[table].allWriterColumn)
    }
    summaryConfig.extra = config
}

const prev = () => {
    activeStep -= 1
}

const next = () => {
    activeStep += 1
}

const submit = () => {
    useRequest.post({ url: "/jobinfo/batchEtl", loadingMessage: "正在提交任务", ...etlConfig }).then(resp => {
        if (resp && resp.status) {
            useElMessage("提交成功")
            nextTick(closePage)
        } else {
            useElMessage.error("提交失败")
        }
    })
}

const closePage = () => {
    const close = tagMenuStore.closeTagMenu(tagMenuStore.getTagMenu.find(e => e.path.startsWith("/task/batchEtl")))
    if (close) {
        router.push("/task")
        broadcastEmitter("refreshTask")
    }
}

const changeStepAnimation = (activeStep, callback) => {
    watch(activeStep, (nextStep, prevStep) => {
        nextTick(() => {
            const animateClass = nextStep > prevStep ? "animate__animated animate__fadeInLeft animate__fast" : "animate__animated animate__fadeInRight animate__fast"
            if (document.querySelector("#step-" + nextStep)) document.querySelector("#step-" + nextStep).classList = animateClass + " full-percent etl-step"
            if (callback) callback(newTabEle?.innerText)
        })
    })

    onDeactivated(() => {
        for (let ele of document.querySelectorAll(".etl-step.animate__animated")) {
            ele.classList.remove("animate__animated")
        }
    })
}

changeStepAnimation(() => activeStep)

getConnection()
</script>

<style>
.batch-etl .step-content {
    height: calc(100% - 125px);
}

.batch-etl .task-step {
    height: 100%;
}

.batch-etl .tables {
    height: calc(100% - 42px);
    padding: 5px;
}

.batch-etl .table-item {
    padding: 5px 10px;
    height: 40px;
    line-height: 40px;
    background: rgb(169 169 169 / 18%);
    border-radius: 3px;
}

.batch-etl .table-item.selected {
    background: #ff9f9f;
}

.batch-etl .el-tab-pane {
    height: calc(100% - 10px) !important;
    padding: 5px;
}

.batch-etl .step-controller {
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 10px;
}

.batch-etl .controller-button {
    background: green;
    padding: 10px 20px;
    border-radius: 3px;
}

.batch-etl .unselectTable {
    height: 70%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: red;
}
</style>